package routers

import (
	"database/sql"
	"net/http"
	"punch/dbs"
	"punch/utils"
	"strconv"

	"github.com/gin-gonic/gin"
)

func LoadTeacher(e *gin.Engine) {
	e.POST("/punc/teacher/add", teacherAddHandler)
	e.POST("/punc/teacher/delete", teacherDeleteHandler)
	e.POST("/punc/teacher/edit", teacherEditHandler)
	e.POST("/punc/teacher/get", teacherGetHandler)
}

// 定义数据表结构体
type Teacher struct {
	Id          int            `db:"id"`
	Org_id      int            `db:"org_id"`
	Org_name    sql.NullString `db:"org_name"`
	Name        string         `db:"name"`
	Phone       string         `db:"phone"`
	Email       string         `db:"email"`
	Duty        string         `db:"duty"`
	Tno         string         `db:"tno"`
	Password    string         `db:"password"`
	Type        int            `db:"type"`
	Create_time string         `db:"create_time"`
	Update_time string         `db:"update_time"`
}

// 定义添加数据结构体
type TeacherParamsAdd struct {
	Org_id int    `json:"org_id" binding:"required"`
	Name   string `json:"name" binding:"required"`
	Phone  string `json:"phone" binding:"required"`
	Email  string `json:"email" binding:"required"`
	Duty   string `json:"duty" binding:"required"`
	Tno    string `json:"tno" binding:"required"`
}

// 定义删除数据结构体
type TeacherParamsDelete struct {
	Id int `json:"id" bingding:"required"`
}

// 定义更新数据结构体
type TeacherParamsEdit struct {
	Id       int    `json:"id" binding:"required"`
	Name     string `json:"name" binding:"required"`
	Phone    string `json:"phone" binding:"required"`
	Email    string `json:"email" binding:"required"`
	Duty     string `json:"duty" binding:"required"`
	Tno      string `json:"tno" binding:"required"`
	Password string `json:"password"`
}

// 定义查询数据结构体
type TeacherParamsGet struct {
	PageNo   int    `json:"pageNo"`
	PageSize int    `json:"pageSize"`
	Id       int    `json:"id"`
	Org_id   int    `json:"org_id"`
	Name     string `json:"name"`
	Phone    string `json:"phone"`
	Email    string `json:"email"`
	Duty     string `json:"duty"`
	Tno      string `json:"tno"`
	Type     int    `json:"type"`
}

func teacherAddHandler(c *gin.Context) {
	if tempUserType, _ := c.Get("Usertype"); tempUserType != "manager" && tempUserType != "teacher" {
		c.JSON(http.StatusOK, gin.H{
			"code": 20020,
			"msg":  "权限不足",
		})
		return
	}

	var params TeacherParamsAdd
	if err := c.ShouldBindJSON(&params); err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 20003,
			"msg":  err.Error(),
		})
		return
	}

	db, err := dbs.Conn(c)
	if err != nil {
		db.Close()
		return
	}

	r, err := db.Exec("insert into teacher(org_id, name, phone, email, duty, tno, password) values(?, ?, ?, ?, ?, ?, ?)",
		params.Org_id, params.Name, params.Phone, params.Email, params.Duty, params.Tno, utils.GetMD5(utils.DEFAULT_PASSWORD))
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 20004,
			"msg":  err.Error(),
		})
		return
	}
	id, err := r.LastInsertId()
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 20000,
			"msg":  err.Error(),
		})
		return
	}

	var teacher []Teacher
	err = db.Select(&teacher, "select t.id, t.org_id, org.name as org_name, t.name, t.phone, t.email, t.duty, t.tno, t.type, t.create_time, t.update_time"+
		" from teacher as t left join org on t.org_id=org.id where t.id=?", id)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 20056,
			"msg":  err.Error(),
		})
		return
	}
	if len(teacher) == 0 {
		c.JSON(http.StatusOK, gin.H{
			"code": 20056,
			"msg":  "添加失败",
			"data": gin.H{
				"Id": id,
			},
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code": 20000,
		"msg":  "添加成功",
		"data": teacher[0],
	})

	db.Close()
}

func teacherDeleteHandler(c *gin.Context) {
	if tempUserType, _ := c.Get("Usertype"); tempUserType != "manager" && tempUserType != "teacher" {
		c.JSON(http.StatusOK, gin.H{
			"code": 20020,
			"msg":  "权限不足",
		})
		return
	}

	var params TeacherParamsDelete
	if err := c.ShouldBindJSON(&params); err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 20003,
			"msg":  err.Error(),
		})
		return
	}

	db, err := dbs.Conn(c)
	if err != nil {
		db.Close()
		return
	}

	_, err = db.Exec("delete from teacher where id=?", params.Id)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 20004,
			"msg":  err.Error(),
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code": 20000,
		"msg":  "删除成功",
		"data": gin.H{
			"Id": params.Id,
		},
	})

	db.Close()
}

func teacherEditHandler(c *gin.Context) {
	if tempUserType, _ := c.Get("Usertype"); tempUserType != "manager" && tempUserType != "teacher" {
		c.JSON(http.StatusOK, gin.H{
			"code": 20020,
			"msg":  "权限不足",
		})
		return
	}

	var params TeacherParamsEdit
	if err := c.ShouldBindJSON(&params); err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 20003,
			"msg":  err.Error(),
		})
		return
	}

	if tempUserType, _ := c.Get("Usertype"); tempUserType == "teacher" {
		if tempID, _ := c.Get("UserID"); params.Id != tempID.(int) {
			c.JSON(http.StatusOK, gin.H{
				"code": 20020,
				"msg":  "权限不足",
			})
			return
		}
	}

	db, err := dbs.Conn(c)
	if err != nil {
		db.Close()
		return
	}

	var teacher []Teacher
	err = db.Select(&teacher, "select * from teacher where id=?", params.Id)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 20023,
			"msg":  err.Error(),
		})
		return
	}
	if len(teacher) == 0 {
		c.JSON(http.StatusOK, gin.H{
			"code": 20030,
			"msg":  "没有此位教师",
			"data": gin.H{
				"Id": params.Id,
			},
		})
		return
	}

	teacher[0].Name = params.Name
	teacher[0].Phone = params.Phone
	teacher[0].Email = params.Email
	teacher[0].Duty = params.Duty
	teacher[0].Tno = params.Tno
	if params.Password != "" {
		teacher[0].Password = utils.GetMD5(params.Password)
	}

	_, err = db.Exec("update teacher set name=?, phone=?, email=?, duty=?, tno=?, password=? where id=?",
		teacher[0].Name, teacher[0].Phone, teacher[0].Email, teacher[0].Duty, teacher[0].Tno, teacher[0].Password, params.Id)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 20025,
			"msg":  err.Error(),
		})
		return
	}

	var teacher2 []Teacher
	err = db.Select(&teacher2, "select t.id, t.org_id, org.name as org_name, t.name, t.phone, t.email, t.duty, t.tno, t.type, t.create_time, t.update_time"+
		" from teacher as t left join org on t.org_id=org.id where t.id=?", params.Id)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 20023,
			"msg":  err.Error(),
		})
		return
	}

	if len(teacher2) == 0 {
		c.JSON(http.StatusOK, gin.H{
			"code": 20025,
			"msg":  "没有此位教师",
		})
		return
	}

	c.JSON(http.StatusOK, gin.H{
		"code": 20000,
		"msg":  "更新成功",
		"data": teacher2[0],
	})

	db.Close()
}

func teacherGetHandler(c *gin.Context) {
	if tempUserType, _ := c.Get("Usertype"); tempUserType != "manager" {
		c.JSON(http.StatusOK, gin.H{
			"code": 20020,
			"msg":  "权限不足",
		})
		return
	}

	var params TeacherParamsGet
	if err := c.ShouldBindJSON(&params); err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 20003,
			"msg":  err.Error(),
		})
		return
	}

	db, err := dbs.Conn(c)
	if err != nil {
		db.Close()
		return
	}

	tempSql := "select t.id, t.org_id, org.name as org_name, t.name, t.phone, t.email, t.duty, t.tno, t.type, t.create_time, t.update_time" +
		" from teacher as t left join org on t.org_id=org.id"
	hasAnd := " where"
	if params.Id != 0 {
		tempSql = tempSql + hasAnd + " t.id=" + strconv.Itoa(params.Id)
		hasAnd = " and"
	}
	if params.Org_id != 0 {
		tempSql = tempSql + hasAnd + " t.org_id=" + strconv.Itoa(params.Org_id)
		hasAnd = " and"
	}
	if params.Name != "" {
		tempSql = tempSql + hasAnd + " t.name like '%" + params.Name + "%'"
		hasAnd = " and"
	}
	if params.Phone != "" {
		tempSql = tempSql + hasAnd + " t.phone like '%" + params.Phone + "%'"
		hasAnd = " and"
	}
	if params.Email != "" {
		tempSql = tempSql + hasAnd + " t.email like '%" + params.Email + "%'"
		hasAnd = " and"
	}
	if params.Duty != "" {
		tempSql = tempSql + hasAnd + " t.duty like '%" + params.Duty + "%'"
		hasAnd = " and"
	}
	if params.Tno != "" {
		tempSql = tempSql + hasAnd + " t.tno like '%" + params.Duty + "%'"
		hasAnd = " and"
	}
	if params.Type != 0 {
		tempSql = tempSql + hasAnd + " t.type=" + strconv.Itoa(params.Type)
		hasAnd = " and"
	}
	tempSql = tempSql + " order by t.create_time desc"
	if params.PageNo != 0 && params.PageSize != 0 {
		tempSql = tempSql + " limit " + strconv.Itoa((params.PageNo-1)*params.PageSize) + "," + strconv.Itoa(params.PageSize)
	}
	var teacher []Teacher
	err = db.Select(&teacher, tempSql)
	if err != nil {
		c.JSON(http.StatusOK, gin.H{
			"code": 20004,
			"msg":  err.Error(),
		})
		return
	}
	c.JSON(http.StatusOK, gin.H{
		"code": 20000,
		"msg":  "查询成功",
		"data": teacher,
	})

	db.Close()
}
